﻿

#region Using Statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Threading;
using System.ComponentModel;
using System.Reflection;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Design;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using Freeform;
using FGame = Freeform.Game;
using XGame = Microsoft.Xna.Framework.Game;
using FComponent = Freeform.Component;
using FViewport = Freeform.Viewport;

#endregion


namespace Freeform
{
    /// <summary>
    /// The world class maintains the state of a world that can be rendered to a screen via a viewport.
    /// </summary>
    public class World : Component
    {

        #region Members

        /// <summary>
        /// Gets a list of all components that are controlled directly by this world.
        /// </summary>
        public ComponentList ComponentList { get; private set; }


        /// <summary>
        /// Gets the viewports that belong to this world.
        /// </summary>
        public List<FViewport> Viewports { get; private set; }


        /// <summary>
        /// Gets or sets the background colour of the world.
        /// </summary>
        public Color BackgroundColour { get; set; }

        #endregion


        #region Init

        /// <summary>
        /// Creates a new world.
        /// </summary>
        /// <param name="Game">A reference to the game instance.</param>
        public World(IGame Game) 
            : base(Game.ComponentList)
        {
            ComponentList = new ComponentList(Game);
            Viewports = new List<FViewport>();
            Game.Worlds.Add(this);
        }

        #endregion


        #region Update

        /// <summary>
        /// Allows the world to update itself.
        /// </summary>
        /// <param name="Time">Provides a snapshot of timing values.</param>
        public override void Update(GameTime Time)
        {
            // Update entity list.
            ComponentList.UpdateLists();

            // Update the viewports that observe this world.
            for (int i = 0; i < Viewports.Count; i++)
                if (Viewports[i].IsEnabled && !Viewports[i].IsDisposed)
                    Viewports[i].Update(Time);

            // Update the entities in the world.
            for (int i = 0; i < ComponentList.Loaded.Count; i++)
                if (ComponentList.Loaded[i].IsEnabled && !ComponentList.Loaded[i].IsDisposed)
                    ComponentList.Loaded[i].Update(Time);

            base.Update(Time);
        }

        #endregion


        #region Dispose

        /// <summary>
        /// Disposes this world and removes it from the game.
        /// </summary>
        protected override void OnDispose()
        {
            base.OnDispose();

            // Dispose all entities in this world.
            while (ComponentList.All.Count > 0)
                ComponentList.All[0].Dispose();

            // Remove this world from the game.
            Game.Worlds.Remove(this);
        }

        #endregion


        #region Utility


        #endregion

    }
}